﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DOTNET101_Properties
{
    class Program
    {
        static void Main(string[] args)
        {
            TestTimePeriod.Test();

            Employee.NumberOfEmployees = 100;
            TestEmployee.Test();
            TestEmployee.Test();
        }
    }

    class TimePeriod
    {
        private double seconds;

        public double Hours
        {
            get { return seconds / 3600; }
            set { seconds = value * 3600; }
        }
    }

    class TestTimePeriod
    {
        public static void Test()
        {
            TimePeriod t = new TimePeriod();

            // Assigning the Hours property causes the 'set' accessor to be called.
            t.Hours = 24;

            // Evaluating the Hours property causes the 'get' accessor to be called.
            System.Console.WriteLine("Time in hours: " + t.Hours);
        }
    }

    public class Date
    {
        private int month = 7;  //"backing store"

        public int Month
        {
            get
            {
                return month;
            }
            set
            {
                if ((value > 0) && (value < 13))
                {
                    month = value;
                }
            }
        }
    }

    public class Employee
    {
        public static int NumberOfEmployees;
        private static int counter;
        private string name;

        // A read-write instance property:
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        // A read-only static property:
        public static int Counter
        {
            get { return counter; }
        }

        // A Constructor:
        public Employee()
        {
            // Calculate the employee's number:
            counter = ++counter + NumberOfEmployees;
        }
    }

    class TestEmployee
    {
        public static void Test()
        {
            Employee e1 = new Employee();
            e1.Name = "Claude Vige";

            System.Console.WriteLine("Employee number: {0}", Employee.Counter);
            System.Console.WriteLine("Employee name: {0}", e1.Name);
        }
    }

    public class Parent
    {
        public virtual int TestProperty
        {
            // Notice the accessor accessibility level.
            protected set { }

            // No access modifier is used here.
            get { return 0; }
        }
    }
    public class Kid : Parent
    {
        public override int TestProperty
        {
            // Use the same accessibility level as in the overridden accessor.
            protected set { }

            // Cannot use access modifier here.
            get { return 0; }
        }
    }

    public interface ISomeInterface
    {
        int TestProperty
        {
            // No access modifier allowed here
            // because this is an interface.
            get;
        }
    }

    public class TestClass : ISomeInterface
    {
        public int TestProperty
        {
            // Cannot use access modifier here because
            // this is an interface implementation.
            get { return 10; }

            // Interface property does not have set accessor,
            // so access modifier is allowed.
            protected set { }
        }
    }

    public class BaseClass
    {
        private string name = "Name-BaseClass";
        private string id = "ID-BaseClass";

        public string Name
        {
            get { return name; }
            set { }
        }

        public string Id
        {
            get { return id; }
            set { }
        }
    }

    public class DerivedClass : BaseClass
    {
        private string name = "Name-DerivedClass";
        private string id = "ID-DerivedClass";

        new public string Name
        {
            get
            {
                return name;
            }

            // Using "protected" would make the set accessor not accessible. 
            set
            {
                name = value;
            }
        }

        // Using private on the following property hides it in the Main Class.
        // Any assignment to the property will use Id in BaseClass.
        new private string Id
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }
    }

    class TestClasses
    {
        public static void Test()
        {
            BaseClass b1 = new BaseClass();
            DerivedClass d1 = new DerivedClass();

            b1.Name = "Mary";
            d1.Name = "John";

            b1.Id = "Mary123";
            d1.Id = "John123";  // The BaseClass.Id property is called.

            System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
            System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);
        }
    }

    class Person
    {
        private string m_name = "N/A";
        private int m_Age = 0;

        // Declare a Name property of type string:
        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                m_name = value;
            }
        }

        // Declare an Age property of type int:
        public int Age
        {
            get
            {
                return m_Age;
            }

            set
            {
                m_Age = value;
            }
        }

        public override string ToString()
        {
            return "Name = " + Name + ", Age = " + Age;
        }
    }

    class TestPerson
    {
        public static void Test()
        {
            // Create a new Person object:
            Person person = new Person();

            // Print out the name and the age associated with the person:
            System.Console.WriteLine("Person details - {0}", person);

            // Set some values on the person object:
            person.Name = "Joe";
            person.Age = 99;
            System.Console.WriteLine("Person details - {0}", person);

            // Increment the Age property:
            person.Age += 1;
            System.Console.WriteLine("Person details - {0}", person);

            // person.SetAge(person.GetAge() + 1); 
        }
    }

    class LightweightCustomer
    {
        public double TotalPurchases { get; set; }
        public string Name { get; private set; } // read-only
        public int CustomerID { get; private set; } // read-only
    }

    public class Contact
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public int ContactNumber { get; set; }
        public int ID { get; private set; } // readonly
    }
}
